//! 文件系统相关工具
use anyhow::anyhow;
use resolve_path::PathResolveExt;
use std::fs;
use std::path::PathBuf;

/// 检查父目录是否存在，不存在则创建
pub fn create_parent_folder(file_path: &PathBuf) -> anyhow::Result<()> {
    let parent_folder = file_path.parent().unwrap();
    if !parent_folder.exists() {
        fs::create_dir_all(parent_folder)?;
    }
    Ok(())
}

/// 解析绝对路径
pub fn resolve_file_path(path: &str) -> anyhow::Result<PathBuf> {
    let path = path.resolve();
    let relative_path = PathBuf::from(path);
    match fs::canonicalize(&relative_path) {
        Ok(r) => Ok(r),
        Err(e) => {
            let err_msg = format!("路径解析失败:{relative_path:?}, err:{e:?}");
            Err(anyhow!(err_msg))
        }
    }
}
/// 解析绝对路径，返回String
pub fn resolve_file_path_string(path: &str) -> anyhow::Result<String> {
    let result = resolve_file_path(path);
    match result {
        Ok(r) => Ok(r.to_string_lossy().into_owned()),
        Err(e) => Err(anyhow!(e)),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_resolve_file_path_string() {
        let test_folder = ".";
        let result = resolve_file_path_string(test_folder);
        assert!(result.is_ok());
    }
    #[test]
    fn test_resolve_file_path_string1() {
        let test_folder = "./src/command/..";
        let result = resolve_file_path_string(test_folder);
        println!("result:{result:?}");
        assert!(result.is_ok());
    }
    #[test]
    fn test_resolve_file_path_string2() {
        let test_folder = "~/";
        let result = resolve_file_path_string(test_folder);
        println!("result:{result:?}");
        assert!(result.is_ok());
    }

    #[test]
    fn test_resolve_file_path_string_error() {
        let test_folder = "testdsjfaklfjskdlajflsakjdf";
        let result = resolve_file_path_string(test_folder);
        assert!(result.is_err());
        assert!(result.unwrap_err().to_string().starts_with("路径解析失败:"));
    }
}
